package gui;


import helperClasses.Book;
import helperClasses.ClassInfo;
import helperClasses.Member;

import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import database.*;
import domainLogic.*;


/*
 * GUI is our GUI controller
 * Here we create the frame, manage events, and ask the Domain Logic for info.
 */
public class GUI implements ActionListener{

	private static final long serialVersionUID = 8198740560678377108L;
	
	//For GridBagLayout, there is a constraint that
	//must be passed when added a component to the Layout.
	protected static GridBagConstraints gbc = new GridBagConstraints();
	SplashPage splashPanel;
	FrontPage frontPanel;
	UserPage userPanel;
	AdminPage adminPanel;
	RegisterPage registerPanel;
	SellPage sellPanel;
	UserInfoPage userInfoPanel;
	JFrame frame;
	
	Database dB;
	DomainLogic dL;
	
	//Constructor
	public GUI(boolean test) throws Exception
	{
		//For Testing Purposes
		//If test is true then use test objects
		if(test)
		{
			dB = new DatabaseTest();
			dL = new DomainLogicTest(dB);
		}
		else
		{
			dB = new DataBaseReal();
			dL = new DomainLogicReal(dB);
		}
		
		frame = new JFrame("UCSD Textbooks!");
	    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    
	    //Size is SplashPage Image size plus a few on both sides.
	    frame.setSize(584, 300);
	    
	    //Starts top left corner of screen
	    frame.setLocation(50, 50);
	    
	    //Content pane calls the constructor for GUI class.
	    splashPanel = new SplashPage(this);
	    frame.setContentPane(splashPanel);
	    
	    frontPanel = new FrontPage(this);
	    userPanel = new UserPage(this);
	    adminPanel = new AdminPage(this);
	    registerPanel = new RegisterPage(this);
	    sellPanel = new SellPage(this);
	    userInfoPanel = new UserInfoPage(this);
	    
	    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    
	    frame.addWindowListener(new WindowAdapter() {
	    	public void windowClosing(WindowEvent e) {
	    		dL.close();
	    	}
	    });
	    //Icon
	    
	    try {                
	    	BufferedImage image = ImageIO.read(new File("./images/watersports1.jpg"));
	    	frame.setIconImage(image);
	    } catch (IOException ex) {
	            //File does not exist or error
	    	    //Simply ignore.
	    }
	    
	    
	    //after creating shows the GUI
	    frame.setVisible(true);
	    
	    return;
	}
	
	public static void main(String s[])
	{
		//Test
		
		//Real
		//new GUI(false);
	}
	
	protected Vector<Vector<Object>> search(String search)
	{
		return dL.searchBooks(search);
	}

	public void actionPerformed(ActionEvent e)
	{
		if ("login".equalsIgnoreCase(e.getActionCommand()))
		{			
			boolean value = dL.isMember(frontPanel.userNameField.getText(),
					frontPanel.userPasswordField.getText());
			
			if(value)
			{
				dL.setCurrentMember(new Member(frontPanel.userNameField.getText(),
					frontPanel.userPasswordField.getText()));
				//System.out.println(dL.getCurrentMember().toString());
				//System.out.println(frontPanel.userNameField.getText());
				//System.out.println(frontPanel.userPasswordField.getText());
				clearPage();
				frame.setSize( 1000, 700);
				if(dL.isAdmin())
					frame.setContentPane(adminPanel);
				else
					frame.setContentPane(userPanel);
				frame.validate();
			}
			else
			{
				JOptionPane.showMessageDialog(null,
					    "Bad Login",
					    "Login error",
					    JOptionPane.ERROR_MESSAGE);
				//frame.setSize(584, 300);
				//frame.setContentPane(splashPanel);
				//frame.validate();
			}
		}
		else if ("register".equalsIgnoreCase(e.getActionCommand()))
		{
			String name = frontPanel.userRNameField.getText();
			String password = frontPanel.userRPasswordField.getText();
			String vpassword = frontPanel.userRPasswordVField.getText();
			String major = frontPanel.userRMajorField.getText();
			String email = frontPanel.userREmailField.getText();
			
			//System.out.println("Name: " + name);
			//System.out.println("password: " + password);
			//System.out.println("vpassword: " + vpassword);
			//System.out.println("major: " + major);
			//System.out.println("email: " + email);
			
			if(name.equals("") || password.equals("") || vpassword.equals("") || email.equals(""))
			{
				JOptionPane.showMessageDialog(null,
					    "Must input at least name, password, and email",
					    "Register error",
					    JOptionPane.ERROR_MESSAGE);
			}
			
			else if(!password.equals(vpassword))
			{
				JOptionPane.showMessageDialog(null,
					    "Password and Verify Password must be the same",
					    "Register error",
					    JOptionPane.ERROR_MESSAGE);
			}
			
			else if(dL.isMember(frontPanel.userRNameField.getText(), null))
			{
				JOptionPane.showMessageDialog(null,
					    "A User already has that name registered.",
					    "Register error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				clearPage();
				dL.registerAccount(new Member(name, password, major, email, Member.USER));
				
				frame.setSize(1000, 700);
				frame.setContentPane(userPanel);
				frame.validate();
			}
		}
		else if("enter".equalsIgnoreCase(e.getActionCommand()))
		{	
			//view Front Page
			frame.setSize(1000, 700);
			frame.setContentPane(frontPanel);
			frame.validate();
			
		}
		else if("info".equalsIgnoreCase(e.getActionCommand()))
		{
			userInfoPanel.updateCurrentMember(dL.getCurrentMember());
			//System.out.println(dL.getCurrentMember().toString());
			userInfoPanel.updatePage();
			frame.setSize(400, 700);
			frame.setContentPane(userInfoPanel);
			frame.validate();
		}
		else if("updatepassword".equalsIgnoreCase(e.getActionCommand()))
		{
			String newPW = userInfoPanel.newPasswordTextField.getText();
			String verifyPW = userInfoPanel.verifyPasswordTextField.getText();
			
			if(newPW.equals(verifyPW))
			{
				dL.editProfile(new Member(userInfoPanel.nameLabel.getText(), newPW));
			}
			else
			{
				JOptionPane.showMessageDialog(null,
					    "Must enter the same password twice",
					    "Update Password Error",
					    JOptionPane.ERROR_MESSAGE);
			}
		}
		else if("userinfoback".equalsIgnoreCase(e.getActionCommand()))
		{
			clearPage();
			frame.setSize(1000, 700);
			frame.setContentPane(userPanel);
			frame.validate();
		}
		else if("sell".equalsIgnoreCase(e.getActionCommand()))
		{
			sellPanel.searchPanel.data.clear();
			sellPanel.searchPanel.data.addAll(dL.getBookList(""));
			
			sellPanel.searchPanel.table.updateUI();
			
			frame.setSize(1000, 700);
			frame.setContentPane(sellPanel);
			frame.validate();
		}
		else if("enterregister".equalsIgnoreCase(e.getActionCommand()))
		{
			frame.setSize( 1000, 700);
			frame.setContentPane(userPanel);
			frame.validate();
		}
		else if("cancelregister".equalsIgnoreCase(e.getActionCommand()))
		{
			frame.setSize(1000, 700);
			frame.setContentPane(frontPanel);
			frame.validate();
		}
		else if("logout".equalsIgnoreCase(e.getActionCommand()))
		{
			clearPage();
			dL.resetCurrentMember();
			frame.setSize( 1000, 700);
			frame.setContentPane(frontPanel);
			frame.validate();
		}
		else if("userinfoadd".equalsIgnoreCase(e.getActionCommand()))
		{
			String className = userInfoPanel.classNameTextField.getText();
			String classMajor = userInfoPanel.classMajorTextField.getText();
			
			if(className.equals("") || classMajor.equals(""))
			{
				JOptionPane.showMessageDialog(null,
					    "Must have a name and major",
					    "Add Class Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				ClassInfo cla = new ClassInfo(className, classMajor);
				if(userInfoPanel.currentMember.isClass(cla))
				{
					JOptionPane.showMessageDialog(null,
						    "Already have this class",
						    "Add Class Error",
						    JOptionPane.ERROR_MESSAGE);
				}
				else
				{
					userInfoPanel.currentMember.addClass(new ClassInfo(className, classMajor));
					userInfoPanel.update();
					dL.editProfile(userInfoPanel.currentMember);
				}
			}
		} else if("userinforemove".equalsIgnoreCase(e.getActionCommand()))
		{
			int index = userInfoPanel.table.getSelectedRow();
			if(index == -1)
			{
				JOptionPane.showMessageDialog(null,
					    "Must select something in the table",
					    "Add Class Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				String className = (String)userInfoPanel.classList.get(index).get(0);
				String classMajor = (String)userInfoPanel.classList.get(index).get(1);
				
				userInfoPanel.currentMember.removeClass(new ClassInfo(className, classMajor));
				userInfoPanel.update();
				dL.editProfile(userInfoPanel.currentMember);			
			}
			
		}else if("updateemail".equalsIgnoreCase(e.getActionCommand()))
		{
			String email = userInfoPanel.emailTextField.getText();
			
			if(email.equals(""))
			{
				JOptionPane.showMessageDialog(null,
					    "Must have a valid email",
					    "Update Email Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				userInfoPanel.currentMember.setEmail(email);
				userInfoPanel.update();
				dL.editProfile(userInfoPanel.currentMember);
			}
		}
		else if("userinfomajor".equalsIgnoreCase(e.getActionCommand()))
		{
			String major = userInfoPanel.majorTextField.getText();
			
			if(major.equals(""))
			{
				JOptionPane.showMessageDialog(null,
					    "Must have valid major",
					    "Update Email Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				userInfoPanel.currentMember.setMajor(major);
				userInfoPanel.update();
				dL.editProfile(userInfoPanel.currentMember);
			}
		}
		else if("adminsearch".equalsIgnoreCase(e.getActionCommand()))
		{
			String name = adminPanel.searchPanel.searchTextField.getText();
			adminPanel.searchPanel.data.clear();
			adminPanel.searchPanel.data.addAll(dL.getUserList(name));
			
			adminPanel.searchPanel.table.updateUI();
		}
		else if("deleteuser".equalsIgnoreCase(e.getActionCommand()))
		{
			int index = adminPanel.searchPanel.table.getSelectedRow();
			if(index == -1)
			{
				JOptionPane.showMessageDialog(null,
					    "Must select something in the table",
					    "Remove User Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				String userName = (String)adminPanel.searchPanel.data.get(index).get(0);
				
				dL.deleteAccount(new Member(userName, null));
				adminPanel.searchPanel.data.clear();
				adminPanel.searchPanel.data.addAll(dL.getUserList(
						adminPanel.searchPanel.searchTextField.getText()));
				
				adminPanel.searchPanel.table.updateUI();
			}
		}
		else if("admincreate".equalsIgnoreCase(e.getActionCommand()))
		{
			String name = adminPanel.adminNameField.getText();
			String pw = adminPanel.adminPasswordField.getText();
			String vpw = adminPanel.adminPasswordVField.getText();
			
			if(name.equals("") || pw.equals("") || vpw.equals(""))
			{
				JOptionPane.showMessageDialog(null,
					    "Did not supply name, password, or verify password.",
					    "Add admin Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else if(!pw.equals(vpw))
			{
				JOptionPane.showMessageDialog(null,
					    "Password and verify password must be the same",
					    "Add admin Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else if(dL.isMember(name, null))
			{
				JOptionPane.showMessageDialog(null,
					    "A User already has that name registered.",
					    "Add admin Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				adminPanel.adminNameField.setText("");
				adminPanel.adminPasswordField.setText("");
				adminPanel.adminPasswordVField.setText("");
				dL.registerAccount(new Member(name, pw, "", "", Member.ADMIN));
			}
		}
		else if("backtouserpage".equalsIgnoreCase(e.getActionCommand()))
		{
			clearPage();
			frame.setSize(1000, 700);
			frame.setContentPane(userPanel);
			frame.validate();
		}
		else if("selldelete".equalsIgnoreCase(e.getActionCommand()))
		{
			int index = sellPanel.searchPanel.table.getSelectedRow();
			if(index == -1)
			{
				JOptionPane.showMessageDialog(null,
					    "Must select something",
					    "Sell Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				String namea = (String)sellPanel.searchPanel.data.get(index).get(0);
				String authora = (String)sellPanel.searchPanel.data.get(index).get(1);
				String editiona = (String)sellPanel.searchPanel.data.get(index).get(2);
				String qualitya = (String)sellPanel.searchPanel.data.get(index).get(3);
				String ISBNa = (String)sellPanel.searchPanel.data.get(index).get(4);
				double pricea = (Double)sellPanel.searchPanel.data.get(index).get(5);


				
				Book book = new Book(namea,authora,editiona,qualitya,ISBNa,dL.getCurrentMember(),pricea);
				dL.cancelPost(book);
				
				sellPanel.searchPanel.data.clear();
				sellPanel.searchPanel.data.addAll(dL.getBookList(sellPanel.searchPanel.searchTextField.getText()));
				
				sellPanel.searchPanel.table.updateUI();
			}
		}
		else if("sellsearch".equalsIgnoreCase(e.getActionCommand()))
		{
			sellPanel.searchPanel.data.clear();
			sellPanel.searchPanel.data.addAll(dL.getBookList(sellPanel.searchPanel.searchTextField.getText()));
			
			sellPanel.searchPanel.table.updateUI();
		}
		else if("selladd".equalsIgnoreCase(e.getActionCommand()))
		{
			String name = sellPanel.bookNameField.getText();
			String author = sellPanel.authorField.getText();
			String edition = sellPanel.editionField.getText();
			String quality = sellPanel.qualityField.getText();
			String ISBN = sellPanel.ISBNField.getText();
			int length = sellPanel.ISBNField.getText().length();
			double price = -1.;
			boolean flagParse = true;
			
			try
			{
				price = Double.parseDouble(sellPanel.priceField.getText());
			}
			catch(Exception ex)
			{
				flagParse = false;
			}
			
			boolean flag = containsOnlyNumbers(ISBN);
			if(name.equals("") || author.equals("") || edition.equals("")
					|| edition.equals("") || quality.equals(""))
			{
				JOptionPane.showMessageDialog(null,
					    "Must have input for all values.",
					    "Add book error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else if(!flag)
			{
				JOptionPane.showMessageDialog(null,
					    "ISBN must be all digits",
					    "Add book error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else if(!(length == 10 || length == 13))
			{
				JOptionPane.showMessageDialog(null,
					    "ISBN must be 10 or 13 digits",
					    "Add book error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else if(!flagParse)
			{
				JOptionPane.showMessageDialog(null,
					    "Must be decimal number only",
					    "Add book error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				dL.postBook(new Book(name, author, edition, quality, ISBN, dL.getCurrentMember(), price));
				
				sellPanel.searchPanel.data.clear();
				sellPanel.searchPanel.data.addAll(dL.getBookList(""));
				
				sellPanel.searchPanel.table.updateUI();
			}
		}
		else if("buybook".equalsIgnoreCase(e.getActionCommand()))
		{
			int index = userPanel.searchPanel.table.getSelectedRow();
			
			if(index == -1)
			{
				JOptionPane.showMessageDialog(null,
					    "Must Select Something",
					    "Buy error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				String namea = (String)userPanel.searchPanel.data.get(index).get(0);
				String authora = (String)userPanel.searchPanel.data.get(index).get(1);
				String editiona = (String)userPanel.searchPanel.data.get(index).get(2);
				String qualitya = (String)userPanel.searchPanel.data.get(index).get(3);
				String ISBNa = (String)userPanel.searchPanel.data.get(index).get(4);
				double pricea = (Double)userPanel.searchPanel.data.get(index).get(5);
				
				Book book = new Book(namea, authora, editiona, qualitya, ISBNa, null, pricea);
				
				String email = dL.buyBook(book);
				
				if(email == null)
				{
					JOptionPane.showMessageDialog(null,
						    "Book Has No Owner",
						    "Buy error",
						    JOptionPane.ERROR_MESSAGE);
				}
				else if(dL.getCurrentMember().getEmail().equals(email))
				{
					JOptionPane.showMessageDialog(null,
						    "You are owner of this book",
						    "Buy error",
						    JOptionPane.ERROR_MESSAGE);
				}
				else
				{
					String message = "If you would like to buy this book\n"
						+ "send an email to: "+email;
					JOptionPane.showMessageDialog(null,
						    message,
						    "Congratulations!",
						    JOptionPane.INFORMATION_MESSAGE);
				}
			}
		}
		
		/*else if("userinforemove".equalsIgnoreCase(e.getActionCommand()))
			String className = userInfoPanel.classNameTextField.getText();
			String classMajor = userInfoPanel.classMajorTextField.getText();
			
			if(className.equals("") || classMajor.equals(""))
			{
				JOptionPane.showMessageDialog(null,
					    "Must have a name and major",
					    "Add Class Error",
					    JOptionPane.ERROR_MESSAGE);
			}
			else
			{
				userInfoPanel.currentMember.addClass(new ClassInfo(className, classMajor));
				userInfoPanel.update();
			}
			
		}*/
	
		return;
	}
	
	public void clearPage()
	{
		adminPanel.clearFields();
		frontPanel.clearFields();
		sellPanel.clearFields();
		userInfoPanel.clearFields();
		userPanel.clearFields();
	}
	
	public boolean containsOnlyNumbers(String str) {
        
        //It can't contain only numbers if it's null or empty...
        if (str == null || str.length() == 0)
            return false;
        
        for (int i = 0; i < str.length(); i++) {

            //If we find a non-digit character we return false.
            if (!Character.isDigit(str.charAt(i)))
                return false;
        }
        
        return true;
    }
}
